package com.ry.demo.concurrent.demo;

import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;

/**
 * @Author: lihui
 * @Date: 2021-12-05 11:45
 * @Description:
 */
public class DoubleCheckSingleton {

    private volatile static DoubleCheckSingleton instance;


    Object socker;

    private DoubleCheckSingleton() {
        socker = new Object();
    }

    public static DoubleCheckSingleton getInstance(){

        // B、因为volatil的内存屏障，导致此时`读操作` 必须等 `写操作`执行完
        if (instance==null){

            // synchronized代码块中 会强制读主内存，会把工作内存中的变量强制刷回主内存；
            // synchronized是可以保证原子性和可见性的
            synchronized(DoubleCheckSingleton.class){
                if (instance==null){
                    // 有可能会出现一种情况，就是指令重排，可能会导致说`DoubleCheckSingleton`对象里面的
                    // `socker`对象还没有再构造函数中初始化还是null,但是`DoubleCheckSingleton` 已经不是null了


                    // A、如果是volatile，会加内存屏障，此时是在`写操作`，也就不能先执行`读操作`
                    DoubleCheckSingleton.instance = new DoubleCheckSingleton();
                }
            }

        }

        return instance;
    }

    public static void main(String[] args) {

        // 线程1

        // 线程2

        Object socker = DoubleCheckSingleton.instance.socker;
        // 有可能会出现空指针
        System.out.println(socker.toString());


    }

}
